#include "hmi_private.h"

#include "esp_log.h"
#include "SD_MMC.h"
#include "buffer.h"

#define TAG "HMI"

uint8_t cmd_buffer[CMD_MAX_SIZE]; // 指令缓存
uint16_t current_screen_id = 0;   // 当前画面ID


void ProcessMessage(uint8_t * message, uint16_t size );

// 定义线程任务函数
void serialReadTask(void *pvParameters)
{
    while (1)
    {
        if (Serial2.available())
        {
            char c = Serial2.read();
            queue_push(c);
            // Serial.printf("Read character: 0X%02X\n",c);
        }
        vTaskDelay(1); // 延时 10 毫秒
    }
}
void HMITask(void *pvParameters)
{
    // 更新标记
    qsize size = 0;

    while (1)
    {
        size = queue_find_cmd(cmd_buffer, CMD_MAX_SIZE); // 从缓冲区中获取一条指令

        if (size > 0 && cmd_buffer[1] != 0x07) // 接收到指令 ，及判断是否为开机提示
        {
            ProcessMessage(cmd_buffer, size); // 指令处理
        }
        else if (size > 0 && cmd_buffer[1] == 0x07) // 如果为指令0x07就软重置STM32
        {
            // __disable_fault_irq();
            // NVIC_SystemReset();
        }
        delay(1);
    }
}

void hmi_init()
{
    // Serial.begin(115200);
    //  Serial1.begin(115200,SERIAL_8N1,15,16);
    Serial2.begin(115200, SERIAL_8N1, 18, 17);

    // uint8_t i = 0x30;
    //  send_byte(i);
    xTaskCreate(
        serialReadTask,   // 任务函数
        "SerialReadTask", // 任务名称
        10000,            // 任务堆栈大小
        NULL,             // 传递给任务函数的参数
        5,                // 任务优先级
        NULL              // 任务句柄
    );

    xTaskCreate(
        HMITask,   // 任务函数
        "HMITask", // 任务名称
        10000,     // 任务堆栈大小
        NULL,      // 传递给任务函数的参数
        5,         // 任务优先级
        NULL       // 任务句柄
    );
}

/*!
 *  \brief  消息处理流程
 *  \param msg 待处理消息
 *  \param size 消息长度
 */
void ProcessMessage(uint8_t *message, uint16_t size)
{
    Buffer frame;

    frame.append(message, size);        // 追加消息到缓冲区
    uint8_t head = frame.read_u8();     // 头部
    uint8_t cmd_type = frame.read_u8(); // 指令类型
    uint8_t ctrl_msg = 0;               // CtrlMsgType-指示消息的类型
    uint16_t screen_id;                 // 画面ID
    uint16_t control_id;                // 控件ID
    uint8_t control_type;               // CtrlMsgType-指示消息的类型
    uint8_t vu8;
    Buffer param;
    String str;

    log_buf_i(message, size);
    // log_i("head:0x%02X,cmd_type:0x%02X", head, cmd_type);

    switch (cmd_type)
    {
    case NOTIFY_TOUCH_PRESS:   // 触摸屏按下
    case NOTIFY_TOUCH_RELEASE: // 触摸屏松开
        NotifyTouchXY(cmd_buffer[1], PTR2U16(cmd_buffer + 2), PTR2U16(cmd_buffer + 4));
        break;
    case NOTIFY_WRITE_FLASH_OK: // 写FLASH成功
        NotifyWriteFlash(1);
        break;
    case NOTIFY_WRITE_FLASH_FAILD: // 写FLASH失败
        NotifyWriteFlash(0);
        break;
    case NOTIFY_READ_FLASH_OK:                        // 读取FLASH成功
        NotifyReadFlash(1, cmd_buffer + 2, size - 6); // 去除帧头帧尾
        break;
    case NOTIFY_READ_FLASH_FAILD: // 读取FLASH失败
        NotifyReadFlash(0, 0, 0);
        break;
    case NOTIFY_READ_RTC: // 读取RTC时间
        NotifyReadRTC(cmd_buffer[2], cmd_buffer[3], cmd_buffer[4], cmd_buffer[5], cmd_buffer[6], cmd_buffer[7], cmd_buffer[8]);
        break;
    case OTA_ACK:
        ctrl_msg = frame.read_u8(); // 指令控制流程
        vu8 = frame.read_u8();      // 指令参数
        // log_i("ctrl_msg:0x%02X,vu8:0x%02X", ctrl_msg, vu8);
        // ProcessMsgOtaAck(ctrl_msg, vu8);
        ota_processor.on_ota_ack(ctrl_msg, vu8);
        break;
    case NOTIFY_CONTROL:
    {
        ctrl_msg = frame.read_u8(); // 指令类型
        log_i("ctrl_msg:0x%02X", ctrl_msg);
        if (ctrl_msg == MSG_GET_CURRENT_SCREEN) // 画面ID变化通知
        {
            screen_id = frame.read_u16(Buffer::BigEnd); // 画面ID
            log_i("screen_id:%d", screen_id);
            NotifyScreen(screen_id); // 画面切换调动的函数
        }
        else
        {
            screen_id = frame.read_u16(Buffer::BigEnd);  // 画面ID
            control_id = frame.read_u16(Buffer::BigEnd); // 控件ID
            control_type = frame.read_u8();              // 控件类型

            // log_i("screen_id:%d,  control_id:%d,  control_type:%d", screen_id, control_id, control_type);
            switch (control_type)
            {
            case kCtrlButton: // 按钮控件
                NotifyButton(screen_id, control_id, frame.read_u8());
                break;
            case kCtrlText: // 文本控件
                str = frame.read_String(); // 文本内容
                NotifyText(screen_id, control_id, (uint8_t *)str.c_str());
                break;
            case kCtrlProgress: // 进度条控件
                NotifyProgress(screen_id, control_id, frame.read_u32());
                break;
            case kCtrlSlider: // 滑动条控件
                NotifySlider(screen_id, control_id, frame.read_u32());
                break;
            case kCtrlMeter: // 仪表控件
                NotifyMeter(screen_id, control_id, frame.read_u32());
                break;
            case kCtrlMenu: // 菜单控件
                NotifyMenu(screen_id, control_id, frame.read_u8(), frame.read_u8());
                break;
            case kCtrlSelector: // 选择控件
                NotifySelector(screen_id, control_id, frame.read_u8());
                break;
            case kCtrlRTC: // 倒计时控件
                NotifyTimer(screen_id, control_id);
                break;
            default:
                log_i("unknown control type");
                break;
            }
        }
        break;
    }
    default:
        log_i("unknown cmd_type:0X%X", cmd_type);
        break;
    }
    frame.clear();
}
